package core;

import objects.userKind;
import objects.Macro;
import java.sql.ResultSet;
import java.sql.SQLException;
import dbManagement.dbManager;
import java.io.Serializable;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import logManagement.Log4k;
import mailManagement.Mailer;

/**
 *
 * @author administrator
 */
public class UserBean implements Serializable {
        private String username;
        private String password;
        private String confirmPassword;
        private int id;
        private String email;
        private String confirmEmail;
        private userKind type = userKind.PATIENT;
        private boolean errorEmail = false;
        private boolean errorPassword = false;
        
        private String googleKey="ABQIAAAADirs_2N1mxtE9SKrRLTpKxT2yXp_ZAY8_ufC3CFXhHIE1NvwkxSil3EL8CjF-Y342WfeOi_nkO5-DQ";

    public String doLogin(){        
        String ret = "";
        
        String msg; // messaggio per Log4K
        msg = "E' stata chiamata doLogin";
        msg += "\n Username: " + this.username + " Password: " + this.password;
        Log4k.debug(this.getClass().getName(), msg);
        
        try {
            dbManager mgr = new dbManager();
            ResultSet sqlRes = mgr.matchingUser(username, password, type);
            mgr.releaseConnection();
            
            msg = "Ho recuperato i dati dal DB. ResultSet = " + sqlRes + "first: " + sqlRes.first();
            Log4k.debug(this.getClass().getName(), msg);
            
            if (sqlRes.last()){
                msg = "Condizione verificata. Estraggo i dati";
                Log4k.debug(this.getClass().getName(), msg);
                
                this.username = sqlRes.getString("username");
                String userKindIDStr = ((type == userKind.PATIENT) ? "patient_id" : "id");
                this.id = sqlRes.getInt(userKindIDStr);
                
                this.setEmail(sqlRes.getString("email_addr"));
                
                msg = "Trovato utente " + this.username + " con id " + this.id;
                Log4k.debug(this.getClass().getName(), msg);
                
                switch (this.type) {
                    case PATIENT: ret = "patient"; 
                    break;
                    case DOCTOR: ret = "doctor";
                    break;
                    case USL: ret = "usl";
                    break;
                    default:
                        ret = "fail";
                        String error = "Nessuno dei tipi dell'enum è risultato valido, controllare!";
                        Log4k.warn(this.getClass().getName(), error);
                        break;
                }
                
                msg = "Recuperato il tipo: " + this.type.toString();
                Log4k.debug(this.getClass().getName(), msg);
                
            } else {
                msg = "Nessun utente trovato";
                Log4k.debug(this.getClass().getName(), msg);
                
                String error = username + " ha provato ad accedere"
                        + " ma non e' registrato nel db, ha sbagliato password"
                        + " oppure non è di tipo " + type + ".";
                Log4k.debug(this.getClass().getName(), error);
                ret = "fail";
            }
        } catch (SQLException ex) {
            msg = "Lanciata SQLException";
            Log4k.debug(this.getClass().getName(), msg);
            Log4k.error(this.getClass().getName(), ex.getMessage()); 
        }
        
        msg = "Termino con valore " + ret;
        Log4k.debug(this.getClass().getName(), msg);
        return ret;
    }
    
   
    public String doLogout(){
        FacesContext context = FacesContext.getCurrentInstance();
        ExternalContext ec = context.getExternalContext();
 
        final HttpServletRequest request = (HttpServletRequest)ec.getRequest();
        request.getSession( false ).invalidate();
        
        return "exit";
    } 
    
    public String backHome(){
        String res = "";
        
        switch (this.type) {
                    case PATIENT: res = "patient"; 
                    break;
                    case DOCTOR: res = "doctor";
                    break;
                    case USL: res = "usl";
                    break;
                    default:
                        res = "fail";
                        String error = "backHome non ha riconosciuto il tipo dell'utente!";
                        Log4k.warn(this.getClass().getName(), error);
                        break;
                }
        return res;
    }
    
        public String resetPassword(){   
            String msg = "Chiamata reset Password";
            Log4k.debug(this.getClass().getName(), msg);
            if(this.username != null && !this.username.equalsIgnoreCase("")){
                dbManager db = new dbManager();
                String sender = Macro.SYSTEM_ADDRESS;
                String receivers[] = {db.getEmailByUsername(this.username, this.type)};
                String subject = "Password Change";
                String text;
                String psw = Macro.generatePassword();
                db.changePassword(this.username, this.type, psw);
                msg = "Password resettata: "+psw;
                Log4k.debug(this.getClass().getName(), msg);
                
                text= "Hi "+this.username+
                        " your new password is "
                        +psw
                        +"\n\n Regards";
                
                db.releaseConnection();
                
                Mailer.mail(sender, receivers, subject, text);
            }
            
            return "exit";
        }
        
        public int numberOfPatient(){
            int res;
            dbManager db = new dbManager();
            res = db.getNumberOfPatients(this.id);
            db.releaseConnection();
            return res;
        }
        
        public int numberOfVisits(){
            int res;
            dbManager db = new dbManager();
            res = db.getNumberOfVisits(this.id);
            db.releaseConnection();
            return res;
        }
        
        public int numberOfScheduled(){
            int res;
            dbManager db = new dbManager();
            res = db.getNumberOfScheduledVisits(this.id);
            db.releaseConnection();
            return res;
        }
        
        public int numberOfCompleted(){
            int res;
            dbManager db = new dbManager();
            res = db.getNumberOfDoneVisits(this.id);
            db.releaseConnection();
            return res;
        }
        
        public void changeEmail(){
            this.flushMessages();
            
            if ( this.getEmail().equals(this.confirmEmail)){
                PatientBean patient = new PatientBean();
                patient.setId(this.id);
                patient.loadMyProfile();
                patient.setEmail(this.getEmail());
                patient.editPatient();
                confirmEmail=null;
            }
            else {
                Log4k.trace(this.getClass().getName(), "Sbagliata email!");
                setErrorEmail(true);
            }
        }
        
        public void changePassword(){
            this.flushMessages();
            
            if(this.password.equals(this.confirmPassword)){
                dbManager db = new dbManager();
                db.changePassword(this.username, this.type, this.password);
                db.releaseConnection();
                confirmPassword=null;
            }
            else{
                Log4k.trace(this.getClass().getName(), "Sbagliata password!");
                setErrorPassword(true);
            }
        }
        
        /* Riporta tutte le variabili di errore allo stato iniziale. */        
        public void flushMessages(){
            this.errorEmail = false;
            this.errorPassword = false;
        }
        
        public boolean isLogged(){
            return this.id != 0;
        }
        
        public boolean isPatient(){
            return (this.type == userKind.PATIENT);                
        }
        
        public boolean isDoctor(){
            return (this.type == userKind.DOCTOR);                
        }
        
        public boolean isUSL(){
            return (this.type == userKind.USL);
        }

    /**
     * @return the username
     */
    public String getUsername() {
        return username;
    }

    /**
     * @param username the username to set
     */
    public void setUsername(String username) {
        this.username = username;
    }

    /**
     * @return the password
     */
    public String getPassword() {
        String p = this.password;
        this.password = null;
        return p;
    }

    /**
     * @param password the password to set
     */
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * @return the id
     */
    public int getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(int id) {
        this.id = id;
    }
    
    /**
     * @return the type
     */
    public userKind getType() {
        return type;
    }

    /**
     * @param type the type to set
     */
    public void setType(userKind type) {
        this.type = type;
    }

    /**
     * @return the confirmPassowrd
     */
    public String getConfirmPassword() {
        return confirmPassword;
    }

    /**
     * @param confirmPassowrd the confirmPassowrd to set
     */
    public void setConfirmPassword(String confirmPassowrd) {
        this.confirmPassword = confirmPassowrd;
    }

    /**
     * @return the confirmEmail
     */
    public String getConfirmEmail() {
        return confirmEmail;
    }

    /**
     * @param confirmEmail the confirmEmail to set
     */
    public void setConfirmEmail(String confirmEmail) {
        this.confirmEmail = confirmEmail;
    }

    /**
     * @return the email
     */
    public String getEmail() {
        return email;
    }

    /**
     * @param email the email to set
     */
    public void setEmail(String email) {
        this.email = email;
    }

    /**
     * @return the errorEmail
     */
    public boolean isErrorEmail() {
        /*boolean tmp;
        tmp = errorEmail;
        Log4k.debug(this.getClass().getName(), ">>>>>>>>>>>>>> errorEmail="+errorEmail+" tmp="+tmp);
        errorEmail = false;
        return tmp;*/
        Log4k.debug(this.getClass().getName(), ">>>>>>>>>>>>>> errorEmail="+errorEmail);
        return errorEmail;
    }

    /**
     * @param errorEmail the errorEmail to set
     */
    public void setErrorEmail(boolean errorEmail) {
        this.errorEmail = errorEmail;
    }

    /**
     * @return the errorPassword
     */
    public boolean isErrorPassword() {
        /*boolean tmp;
        tmp = errorPassword;
        Log4k.debug(this.getClass().getName(), ">>>>>>>>>>>>>> errorPassword="+errorPassword+" tmp="+tmp);
        errorPassword = false;
        return tmp;*/
        Log4k.debug(this.getClass().getName(), ">>>>>>>>>>>>>> errorPassword="+errorPassword);
        return errorPassword;
    }

    /**
     * @param errorPassword the errorPassword to set
     */
    public void setErrorPassword(boolean errorPassword) {
        this.errorPassword = errorPassword;
    }

    /**
     * @return the googleKey
     */
    public String getGoogleKey() {
        return googleKey;
    }

    /**
     * @param googleKey the googleKey to set
     */
    public void setGoogleKey(String googleKey) {
        this.googleKey = googleKey;
    }

}
